package com.blue.excel.demo;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Administrator on 2017/11/17.
 */
public class Tool {

    List<CellRangeAddress> mergeRegions = new ArrayList<>();

    Sheet sheet;

    public Tool(Sheet sheet) {
        this.sheet = sheet;
    }

    public Tool deleteColumns(Integer... indexs){

        for(Integer index : indexs){
            deleteColumn(index);
        }

        return this;
    }

    public void autoColumnWidth(Integer... columns){
        for(Integer index : columns){
            autoColumnWidth(index);
        }
    }


    public void deleteColumn(Integer index){
        for(int i = 0; i < sheet.getLastRowNum(); i++){
            Row currentRow = sheet.getRow(i);
            if(currentRow != null){
                Cell cell = currentRow.getCell(index);
                if(cell != null){
                    currentRow.removeCell(cell);

                }
            }
        }

        saveMerges(index + 1);
        moveLeftOneStep(index + 1);
        reMakeMerges();
//        moveLeftOneStep(sheet,index + 1);
    }


    public void saveMerges(Integer index){
        int mergeRegionNum = sheet.getNumMergedRegions();
        for(int i = mergeRegionNum - 1; i >= 0; i --){
            CellRangeAddress mergedRegion = sheet.getMergedRegion(i);
            if(mergedRegion.getFirstColumn() >= index){
                mergedRegion.setFirstColumn(mergedRegion.getFirstColumn() - 1);
                mergedRegion.setLastColumn(mergedRegion.getLastColumn() - 1);
                mergeRegions.add(mergedRegion);
                sheet.removeMergedRegion(i);
            }
            else if(mergedRegion.getLastColumn() >= index){
                mergedRegion.setLastColumn(mergedRegion.getLastColumn() - 1);
                mergeRegions.add(mergedRegion);
                sheet.removeMergedRegion(i);
            }
        }
    }

    public void reMakeMerges(){
        for(CellRangeAddress cellRangeAddress : mergeRegions){
            sheet.addMergedRegion(cellRangeAddress);
        }
        mergeRegions.clear();
    }

    public void moveLeftOneStep(Integer index){
        for(int i = sheet.getFirstRowNum(); i <= sheet.getLastRowNum(); i++){
            Row currentRow = sheet.getRow(i);
            for(int j = index; j < currentRow.getLastCellNum(); j++){
                Cell sourceCell = currentRow.getCell(j);
                Cell targetCell = getOrCreateCell(currentRow, j - 1);
                if(sourceCell != null){
                    copyCellValue(targetCell, sourceCell,true);
                    currentRow.removeCell(sourceCell);
                }

            }
        }
    }


    protected Cell getOrCreateCell(Row row,int index){
        Cell cell = row.getCell(index);
        if(cell == null){
            cell = row.createCell(index);
        }
        return cell;
    }


    protected void copyCellValue(Cell target,Cell source,boolean copyStyle){
        int cellType = source.getCellType();
        if(copyStyle){
            CellStyle sourceCellStyle = source.getCellStyle();
            target.setCellStyle(sourceCellStyle);
        }
        switch (cellType){
            case Cell.CELL_TYPE_STRING:
                String strValue = source.getStringCellValue();
                if(strValue != null){
                    target.setCellValue(strValue);
                }
                break;
            case Cell.CELL_TYPE_NUMERIC:
                Double doubleValue = source.getNumericCellValue();
                if(doubleValue != null){
                    target.setCellValue(doubleValue);
                }
                break;
            case Cell.CELL_TYPE_BOOLEAN:
                Boolean booleanValue = source.getBooleanCellValue();
                if(booleanValue != null){
                    target.setCellValue(booleanValue);
                }
                break;
        }
    }




    public int getContentLength(Cell cell){
        int cellType = cell.getCellType();
        String strValue = null;
        switch (cellType){
            case Cell.CELL_TYPE_NUMERIC:
                strValue = String.valueOf(cell.getNumericCellValue());
                break;
            case Cell.CELL_TYPE_STRING:
                strValue = cell.getStringCellValue();
                break;
            case Cell.CELL_TYPE_BOOLEAN:
                strValue = String.valueOf(cell.getBooleanCellValue());
                break;
        }
        if(strValue == null){
            return 0;
        }
        return strValue.getBytes().length * 256;
    }


    public void autoColumnWidth(int column) {
        int width = 0;
        for (int i = sheet.getFirstRowNum(); i <= sheet.getLastRowNum(); i++) {
            Row currentRow = sheet.getRow(i);
            if(currentRow != null){
                Cell cell = currentRow.getCell(column);
                if(cell != null){
                    int length = getContentLength(cell);
                    if(length > width){
                        width = length;
                    }
                }
            }
        }
        sheet.setColumnWidth(column,width);
    }
}
